<?php
//-------------------------------------------------------------------------
// OVIDENTIA http://www.ovidentia.org
// Ovidentia is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// 
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//-------------------------------------------------------------------------
/**
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
 * @copyright Copyright (c) 2006 by CANTICO ({@link http://www.cantico.fr})
 */
//include_once 'base.php';

//require_once $GLOBALS['babInstallPath'] . 'utilit/devtools.php';
require_once $GLOBALS['babInstallPath'] . '/addons/widgets/widgets/item.class.php';
require_once $GLOBALS['babInstallPath'] . '/addons/widgets/widgets/action.class.php';







/**
 * The Widget_Widget class is the base class of all user interface objects.
 *
 * @abstract
 */
class Widget_Widget extends Widget_Item
{

	private $_name;
	private $_initScript;
	private $_cssClasses;


	/**
	 * This property store a disable/enable state for form fields or one of the parent items
	 * @see Widget_Widget::isDisabled()
	 * @see Widget_Widget::disable()
	 * @see Widget_Widget::enable()
	 * @var bool
	 */
	private $_disabled = null;

	/**
	 * This property store a boolean to allow or disallow a form field or multiple form fields with one of the parent items
	 * If form field is not allowed, value will be displayed without field
	 * @see Widget_Widget::isEditMode()
	 * @see Widget_Widget::setEditMode()
	 * @see Widget_Widget::setDisplayMode()
	 * @var bool
	 */
	private $_form_fields_disallowed = null;
	

	/**
	 * Set persistent status for display state of the widget
	 * if widget is persistent, informations may be stored in cookies or in session to maintain aspect beetween pages
	 * @var bool
	 */
	private $_persistent;

	/**
	 * @param string $id	The item unique id.
	 */
	public function __construct($id = null)
	{
		parent::__construct($id);
		$this->setName('');
		$this->setClasses('');
		$this->setInitScript('');
//		$this->_slots = array();
//		$this->_actions = array();
	}


	/**
	 * Sets the name of the wigdet.
	 *
	 * The name of the widget will be used to generate the name of the corresponding form element.
	 * This method returns the widget itself so that other methods can be chained.
	 *
	 * @param string $name
	 * @return Widget_Widget
	 */
	public function setName($name)
	{
		assert('is_string($name); /* The "name" parameter must be a string. */');
		$this->_name = $name;
		return $this;
	}


	/**
	 * Returns the widget name.
	 *
	 * @return string
	 */
	public function getName()
	{
		return $this->_name;
	}


	/**
	 * @return array
	 */
	protected function getNamePath() {
		$namePath = array();
		/* @var $widget Widget_Item */
		for ($widget = $this; $widget; $widget = $widget->getParent()) {
			$name = (string) $widget->getName();
			if ('' !== $name) {
				array_unshift($namePath, $name);
			}
		}

		return $namePath;
	}


	/**
	 * Sets the parent of the widget.
	 *
	 * @param Widget_Item $parent
	 * @return Widget_Widget
	 */
	public function setParent($parent)
	{
		assert('is_null($parent) || $parent instanceof Widget_Item; /* The "parent" parameter must be a Widget_Item object. */');
		parent::setParent($parent);
		return $this;
	}


	/**
	 * Enables the widget.
	 * 
	 * @return Widget_Widget
	 */
	public function enable()
	{
		$this->_disabled = false;
		return $this;
	}


	/**
	 * Disables the widget.
	 * 
	 * @return Widget_Widget
	 */
	public function disable()
	{
		$this->_disabled = true;
		return $this;
	}


	/**
	 * Get disabled status on widget or from parent
	 * 
	 * @return boolean
	 */
	public function isDisabled() {
		if (null === $this->_disabled) {
			$parent = $this->getParent();
			if (null === $parent) {
				return false;
			}
			
			return $parent->isDisabled();
		}
		
		return $this->_disabled;
	}





	/**
	 * Enables the widget.
	 * 
	 * @return Widget_Widget
	 */
	public function setEditMode()
	{
		$this->_form_fields_disallowed = false;
		return $this;
	}


	/**
	 * Disables the widget.
	 * 
	 * @return Widget_Widget
	 */
	public function setDisplayMode()
	{
		$this->_form_fields_disallowed = true;
		return $this;
	}
	


	/**
	 * Get form field disallowed status on widget or from parent
	 * 
	 * @return boolean
	 */
	public function isDisplayMode() {
		if (null === $this->_form_fields_disallowed) {
			$parent = $this->getParent();
			if (null === $parent) {
				return false;
			}
			
			return $parent->isDisplayMode();
		}
		
		return $this->_form_fields_disallowed;
	}


	
	/**
	 * Returns the page to which this widget is attached.
	 *
	 * @return Widget_Page|null
	 */
	public function getPage()
	{
		for ($widget = $this; $widget && (!($widget instanceof Widget_Page)); $widget = $widget->getParent()) {
			;
		}

		return $widget;
	}


	/**
	 * The widget will automatically try to save its state (in a cookie for example), so that
	 * it will be in the same state the next time the containing page is displayed.
	 *
	 * @param bool $persistent
	 * @return Widget_Widget
	 */
	public function setPersistent($persistent = true)
	{
		assert('is_bool($persistent); /* The "persistent" parameter must be a boolean. */');
		$this->_persistent = $persistent;
		return $this;
	}

	/**
	 * Returns whether the widget has been set in persistent mode.
	 * 
	 * When in persistent mode a widget will keep its state in a cookie.
	 * 
	 * @return bool
	 */
	public function isPersistent()
	{
		return $this->_persistent;
	}


	/**
	 * Sets the css classes of the widget.
	 *
	 * @param string|array $classes		A string containing space separated css class names or an array containing class names
	 * @return Widget_Widget
	 */
	function setClasses($classes)
	{
		assert('is_array($classes) || is_string($classes); /* The "classes" parameter must be a string or a array. */');
		if ($classes === '') {
			$classes = array();
		} elseif (is_string($classes)) {
			$classes = explode(' ', $classes);
		}
		if (is_array($classes)) {
			$this->_cssClasses = $classes;
			array_unique($this->_cssClasses);
		}
		return $this;
	}


	/**
	 * Appends the css classes to the classes of the widget.
	 *
	 * @param string|array $classes		A string containing space separated css class names or an array containing class names
	 * @return Widget_Widget
	 */
	function addClasses($classes)
	{
		if (is_string($classes)) {
			$classes = explode(' ', $classes);
		}
		if (is_array($classes)) {
			$this->_cssClasses = array_merge($this->_cssClasses, $classes);
			array_unique($this->_cssClasses);
		}
		return $this;
	}



	public function getClasses()
	{
		$classes = parent::getClasses();
		if ($this->isPersistent()) {
			$classes[] = 'widget-persistent';
		} 
		return $classes;
	}


	
//	/**
//	 * Enter description here...
//	 *
//	 * @param string $slotName
//	 * @param string $slotBody
//	 */
//	function addSlot($slotName, $slotBody)
//	{
//		$this->_slots[$slotName] = $slotBody;
//		return $this;
//	}


	function setInitScript($script)
	{
		$this->_initScript = $script;
	}
	

//	/**
//	 * Sets the script called on drop event.
//	 *
//	 * @param string		$dropScript
//	 * @return Widget_Widget
//	 */
//	public function onDrop($dropScript = null)
//	{
//		$this->_onDrop = $dropScript;
//		return $this;
//	}
//
//
//	protected function getMetaData()
//	{
//		$metadata = '';
//		if (isset($this->_onDrop)) {
//			$metadata .= ' dropurl="' . htmlentities($this->_onDrop) . '" ';
//		}
//		return $metadata;
//	}


//	/**
//	 * Adds an action to the widget.
//	 *
//	 * @param Widget_Action $action
//	 */
//	public function addAction(Widget_Action $action)
//	{
//		$this->_actions[] = $action;
//		return $this;
//	}


//	/**
//	 * Returns the actions associated to this widget.
//	 *
//	 * @return array		An array of Widget_Action
//	 */
//	protected function getActions()
//	{
//		return $this->_actions;
//	}

	
//	/**
//	 * Returns the html for a contextual menu with actions associated to this widget.
//	 *
//	 * @return string
//	 */
//	protected function getHtmlActions()
//	{
//		$actions = $this->getActions();
//		$html = '<div class="contextMenu" id="' . $this->getId() . '_menu">';
//		$html .= '<ul class="Widget_Actions">';
//		foreach ($actions as $action) {
//			$href = $action->getUrl();
//			if ($action->isRelative()) {
//				$href = $GLOBALS['babAddonUrl'] . $href;
//			}
//			$html .= '<li class="Widget_Action"><a onclick="' . $action->getOnClick() . '" href="' . $href . '" target="' . $action->getTarget() . '">' . $action->getLabel() . '</a></li>';
//		}
//		$html .= '</ul>';
//		$html .= '</div>';
//		return $html;
//	}


	/**
	 * Dump widget content as an ascii tree.
	 * For debugging purpose.
	 *
	 * @param string $prefix
	 * @return string
	 */
	public function dump($prefix = '')
	{
		$dumpString = $prefix . '&#9474;' . "\n" . $prefix . '&#9500;&#9472;&#9472;&#9472;' . get_class($this) . '("<b>' . $this->getId() . '</b>")';
		$name = $this->getName();
		if ($name !== '') {
			$dumpString .= ' name="' . $this->getName() . '"';
		}
		
		$parent = $this->getParent();
		
		if (null === $parent) {
			$parent = 'null';
		} else {
			$parent = $parent->getId();
		}

		$dumpString .= sprintf(' <small>parent=%s</small>', $parent);
		
		
		
		return $dumpString;
	}
	
	public function __toString()
	{
		return $this->dump();
	}
}

